#ifndef _MATRIX_4X4_H_
#define _MATRIX_4X4_H_

#include "Vector3.h"

using namespace std;

class Matrix4x4
{

	// column major
	// i.e.
	//  _            _
	// |  0  4  8 12  |
	// |  1  5  9 13  |
	// |  2  6 10 14  |
	// |_ 3  7 11 15 _|


public:

	float m[16];

	// ctors
	Matrix4x4();
	Matrix4x4( float m_[16] );
	Matrix4x4( const Matrix4x4 & m_ );
	Matrix4x4( float m0, float m4, float m8,  float m12,
			   float m1, float m5, float m9,  float m13,
			   float m2, float m6, float m10, float m14,
			   float m3, float m7, float m11, float m15 );

	// named ctors
	static Matrix4x4 RotationMatrix( float theta, const Vector3 & axis );
	static Matrix4x4 TranslationMatrix( const Vector3 & v );
	static Matrix4x4 Inverse( const Matrix4x4 & m_ );

	void		loadIdentity();
	void		loadRotate( double theta, const Vector3 & axis );
	void		loadTranslate( const Vector3 & v );
	void		invert();

	// operators
	Vector3		operator * ( const Vector3 & v ) const;
	Matrix4x4	operator * ( const Matrix4x4 & m_ ) const;
	Matrix4x4	operator *= ( const Matrix4x4 & m_ );

	friend ostream & operator << ( ostream & o, const Matrix4x4 & m_ );

};


#endif

